import React from 'react';
import ReactDOM from 'react-dom/client';
import axios from 'axios';
import App from './app';

function parseLocationSearch(search: any = '?') {
  const param: any = {};
  search?.replace(/([^?&]+)=([^?&]+)/g, function (s: string, v: string, k: string) {
    param[v] = decodeURIComponent(k);
    return k + '=' + v;
  });
  return param;
}

function getData(code: string) {
  const objectString = code.replace(/^[\s\S]*?export default\s*/, '').replace(/;?\s*$/, '');

  // 使用 Function 构造函数创建一个函数，返回解析后的对象
  const resultFunc = new Function(`return ${objectString}`);

  // 执行函数，获取解析后的对象
  const result = resultFunc();
  return result;
}

function request(url: string, baseURL?: string) {
  return axios({
    url,
    withCredentials: false,
    baseURL,
  }).then((res: any) => {
    return getData(res.data);
  });
}

async function getDefaultProps(baseUrl?: string) {
  try {
    const data = await request(`/material.ts`, baseUrl);
    return data;
  } catch (e) {}
}

async function getMockJson(baseUrl?: string) {
  let material: any;
  let data: any;
  try {
    material = await getDefaultProps(baseUrl);
    const params = parseLocationSearch(location.search);
    const mock = params?._mock;
    if (mock) {
      try {
        data = await request(`/mock/${mock}.ts`, baseUrl);
      } catch (e) {
        data = await request(`/mock/default.ts`, baseUrl);
      }
    }
  } catch (e) {}
  return {
    material,
    data: data || material?.initProps,
  };
}

async function render(Component: any, { root = 'root', baseUrl }: any = { root: 'root' }) {
  const rootDom = ReactDOM.createRoot(
    (typeof root === 'string' ? (document.getElementById(root) as HTMLElement) : root) ||
      document.body,
  );

  const { material, data } = await getMockJson(baseUrl);
  rootDom.render(
    <App>
      <Component __material={material} {...data} />
    </App>,
  );
}

export { render };
